<template>
  <button
    :type="type"
    :class="[
      'btn',
      sizeClass,
      variantClass,
      isPresetColor ? colorClass : 'btn-default',
      { 
        'btn-block': block,
        'btn-round-full': round,
        'disabled': isDisabled,
        'loading': loading,
        'icon-only': iconOnly
      }
    ]"
    :style="[customColorStyle]"
    :disabled="isDisabled"
    @click="handleClick"
  >
    <g-icon
      v-if="loading && !$slots.loading"
      name="mdi:loading"
      class="btn-icon"
      :size="iconSize"
      spin
    />
    <slot name="loading" v-if="loading && $slots.loading" />
    <g-icon
      v-if="icon && !loading"
      :name="icon"
      class="btn-icon"
      :size="iconSize"
    />
    <slot />
    <g-icon
      v-if="suffixIcon && !loading"
      :name="suffixIcon"
      class="btn-icon"
      :size="iconSize"
    />
  </button>
</template>

<script setup lang="ts">
import { computed, useSlots } from 'vue'
import GIcon from '@/components/icon/Index.vue'

// Props 定义
interface Props {
  type?: 'button' | 'submit' | 'reset'
  variant?: 'fill' | 'light' | 'line' | 'dashed' | 'text' | 'link'
  size?: 'large' | 'big' | 'default' | 'small' | 'mini'
  color?: 'default' | 'primary' | 'info' | 'success' | 'warning' | 'error' | string
  disabled?: boolean
  icon?: string
  suffixIcon?: string
  loading?: boolean
  round?: boolean
  block?: boolean
}

// Props 默认值
const props = withDefaults(defineProps<Props>(), {
  type: 'button',
  variant: 'fill',
  size: 'default',
  color: 'default',
  disabled: false,
  iconPosition: 'left',
  loading: false,
  round: false,
  block: false
})

// Emits 定义
const emit = defineEmits<{
  (e: 'click', event: MouseEvent): void
}>()

// 颜色映射
const colorMap = [
  'default',
  'primary',
  'info',
  'success',
  'warning',
  'error'
]

// 图标尺寸映射
const iconSizeMap = {
  large: '18',
  big: '16',
  default: '14',
  small: '14',
  mini: '12'
}

const slots = useSlots()
// 计算属性
const sizeClass = computed(() => `btn-size-${props.size}`)
const variantClass = computed(() => `btn-${props.variant}`)
const colorClass = computed(() => `btn-${props.color}`)
const isPresetColor = computed(() => colorMap.includes(props.color))
const iconSize = computed(() => iconSizeMap[props.size])
const iconOnly = computed(() => (props.icon || props.loading) && !slots.default)
const isDisabled = computed(() => props.disabled || props.loading)

// 自定义颜色样式计算
const customColorStyle = computed(() => {
  if (isPresetColor.value) return ''
  
  const color = props.color.toLowerCase()
  const lightColor = `color-mix(in srgb, ${color} 10%, white)`
  const hoverColor = `color-mix(in srgb, ${color} 80%, white)`
  const lightHoverColor = `color-mix(in srgb, ${color} 40%, white)`

  return `
    --btn-default-base: ${color};
    --btn-default-hover: ${hoverColor};
    --btn-default-lhover: ${lightHoverColor};
    --btn-default-light: ${lightColor};
    --btn-default-text: ${color};
    --btn-default-ptext: white;
  `
})

// 事件处理
const handleClick = (event: MouseEvent) => {
  if (isDisabled.value) {
    event.preventDefault()
    event.stopPropagation()
    return
  }
  emit('click', event)
}
</script>

<style lang="scss">
@use '../../assets/base' as *;

// Mixins
@mixin button-variant($color-name) {
  &.btn-#{$color-name} {
    --btn-bg-color: var(--btn-#{$color-name}-base);
    --btn-border-color: var(--btn-#{$color-name}-base);
    --btn-text-color: var(--btn-#{$color-name}-ptext);

    &:not(.disabled):hover {
      --btn-bg-color: var(--btn-#{$color-name}-hover);
      --btn-border-color: var(--btn-#{$color-name}-hover);
    }

    &.btn-light {
      --btn-bg-color: var(--btn-#{$color-name}-light);
      --btn-border-color: var(--btn-#{$color-name}-light);
      --btn-text-color: var(--btn-#{$color-name}-text);

      &:not(.disabled):hover {
        --btn-bg-color: var(--btn-#{$color-name}-base);
        --btn-border-color: var(--btn-#{$color-name}-base);
        --btn-text-color: var(--btn-#{$color-name}-ptext);
      }
    }

    &.btn-dashed {
      border-style: dashed;
    }

    &.btn-line, &.btn-dashed {
      --btn-bg-color: transparent;
      --btn-border-color: var(--btn-#{$color-name}-base);
      --btn-text-color: var(--btn-#{$color-name}-text);

      &:not(.disabled):hover {
        --btn-bg-color: transparent;
        --btn-border-color: var(--btn-#{$color-name}-lhover);
        --btn-text-color: var(--btn-#{$color-name}-text);
      }
    }

    &.btn-text, &.btn-link {
      --btn-bg-color: transparent;
      --btn-border-color: transparent;
      --btn-text-color: var(--btn-#{$color-name}-text);
    }
    &.btn-text {
      &:not(.disabled):hover {
        --btn-bg-color: var(--btn-#{$color-name}-light);
        --btn-border-color: var(--btn-#{$color-name}-light);
        --btn-text-color: var(--btn-#{$color-name}-text);
      }
    }
    &.btn-link {
      &:not(.disabled):hover {
        --btn-bg-color: transparent;
        --btn-border-color: transparent;
        --btn-text-color: var(--btn-#{$color-name}-text);
        text-decoration: underline;
      }
    }
  }
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  height: var(--default-height);
  padding: 0 1em;
  border: 1px solid var(--btn-border-color);
  background-color: var(--btn-bg-color);
  color: var(--btn-text-color);
  cursor: pointer;
  transition: all 0.2s;
  font-size: 14px;
  line-height: 1.5;
  outline: none;
  position: relative;
  white-space: nowrap;
  vertical-align: middle;
  border-radius: var(--radius);

  &:disabled, &.disabled {
    cursor: not-allowed;
    opacity: 0.65;
  }

  &.loading {
    cursor: not-allowed;
    opacity: 0.65;
  }

  // Apply variants for each color
  @include button-variant('default');
  @include button-variant('primary');
  @include button-variant('info');
  @include button-variant('success');
  @include button-variant('warning');
  @include button-variant('error');

  // Size variants
  &.btn-size-large {
    height: var(--large-height);
    font-size: 16px;
    &.icon-only {
      padding: 0;
      width: var(--large-height);
      height: var(--large-height);
    }
  }

  &.icon-only {
    padding: 0;
    width: var(--default-height);
    height: var(--default-height);
  }

  &.btn-size-big {
    height: var(--big-height);
    font-size: 16px;
    &.icon-only {
      padding: 0;
      width: var(--big-height);
      height: var(--big-height);
    }
  }

  &.btn-size-small {
    height: var(--small-height);
    font-size: 14px;
    &.icon-only {
      padding: 0;
      width: var(--small-height);
      height: var(--small-height);
    }
  }

  &.btn-size-mini {
    height: var(--mini-height);
    font-size: 12px;
    &.icon-only {
      padding: 0;
      width: var(--mini-height);
      height: var(--mini-height);
    }
  }

  &.btn-round-full {
    border-radius: 9999px;
  }

  // Block variant
  &.btn-block {
    display: flex;
    width: 100%;
  }
}
</style>